<!--
 * @description: 环境设置弹窗
 * @fileName: EnvironmentDialog.vue
 * @author: ssr
 * @date: 2023-01-05 10:31:33
 * @version: V1.0.0
! -->
<script setup lang="ts">
import type { IEnvItem } from "@@/apis/scn/type"
import { useScenarioStore } from "@/pinia/stores/scenario"
import { createEnv, deleteEnv, getEnvDetail, updateEnv } from "@@/apis/scn"
import Compass from "@@/components/compass/index.vue"
import { Edit, Minus, Plus } from "@element-plus/icons-vue"
import { ElMessage } from "element-plus"
import { reactive, ref, toRefs } from "vue"

const scenarioStore = useScenarioStore()
const formRef = ref()

// 状态数据
const state = reactive<{
  visible: boolean
  confirmLoading: boolean
  editName: boolean
  formState: IEnvItem
}>({
  visible: false,
  confirmLoading: false,
  editName: false,
  formState: {
    scnId: "",
    envObjName: "",
    id: "",
    // 海况等级
    seaStateLevel: 2,
    // 风向
    windCou: 290,
    // 风速
    windVel: 15
  }
})

// 解构状态数据
const { visible, confirmLoading, editName, formState } = toRefs(state)

// 海况等级标记
const marks = ref({
  0: "0",
  9: "9"
})

// 环境选项
const options = ref<IEnvItem[]>([])

/**
 * 更新风向
 */
function updateRotate(rotate: number) {
  state.formState.windCou = rotate
}

/**
 * 显示环境设置对话框
 */
function handleShowDialog() {
  // 查询环境信息
  getEnvDetail(scenarioStore.scnId).then(({ data }) => {
    if (data && data.length > 0) {
      options.value = data
      state.formState.id = options.value[0].id
      state.formState.envObjName = options.value[0].envObjName
      state.formState.seaStateLevel = options.value[0].seaStateLevel
      state.formState.windCou = options.value[0].windCou
      state.formState.windVel = options.value[0].windVel
    } else {
      options.value = []
      state.formState.id = ""
      state.formState.envObjName = ""
      state.formState.seaStateLevel = 2
      state.formState.windCou = 290
      state.formState.windVel = 15
    }
    state.editName = false
    state.visible = true
  })
}

/**
 * 编辑名称
 */
function editNameClick() {
  const optionsValue = options.value.filter(item => item.id === state.formState.id)
  if (optionsValue.length > 0) {
    state.formState.envObjName = optionsValue[0].envObjName
    state.editName = !state.editName
  }
}

/**
 * 选择环境对象
 */
function handleChange(item: string) {
  const optionsValue = options.value.filter(itemX => itemX.id === item)
  if (optionsValue.length > 0) {
    state.formState.id = optionsValue[0].id
    state.formState.envObjName = optionsValue[0].envObjName
    state.formState.seaStateLevel = optionsValue[0].seaStateLevel
    state.formState.windCou = optionsValue[0].windCou
    state.formState.windVel = optionsValue[0].windVel
  }
}

/**
 * 新增环境对象
 */
function plus() {
  options.value.push({
    envObjName: `default_${options.value.length + 1}`,
    id: `temp_${options.value.length}`,
    create: "create"
  } as IEnvItem)
  state.formState.id = options.value[options.value.length - 1].id
  state.formState.envObjName = options.value[options.value.length - 1].envObjName
}

/**
 * 删除环境对象
 */
function minus(id: string) {
  const optionsValue = options.value.filter(item => item.id === id)
  if (optionsValue.length === 0) return

  if (optionsValue[0].create === "create") {
    options.value = options.value.filter(item => item.id !== id)
    if (options.value.length > 0) {
      handleChange(options.value[0].id)
    }
  } else {
    deleteEnv(optionsValue[0].id)
      .then(({ code }) => {
        if (code === 200) {
          handleShowDialog()
          ElMessage.success("删除成功")
        } else {
          ElMessage.error("删除失败")
        }
      })
      .catch((err) => {
        ElMessage.error("删除失败")
        console.error(err)
      })
  }
}

/**
 * 保存环境设置
 */
function handleConfirm() {
  formRef.value.validate((valid: boolean) => {
    if (!valid) return

    if (scenarioStore.scnId) {
      state.confirmLoading = true
      state.formState.scnId = scenarioStore.scnId

      const optionsValue = options.value.find(item => item.id === state.formState.id)
      if (!optionsValue) {
        state.confirmLoading = false
        return
      }

      const savePromise = optionsValue.create === "create"
        ? createEnv(state.formState)
        : updateEnv(state.formState)

      savePromise
        .then(({ code, message: msg }) => {
          if (code === 200) {
            ElMessage.success("保存成功")
            state.visible = false
          } else {
            ElMessage.error(msg || "保存失败")
          }
        })
        .catch(() => {
          ElMessage.error("保存失败")
        })
        .finally(() => {
          state.confirmLoading = false
        })
    }
  })
}

/**
 * 取消
 */
function handleCancel() {
  state.visible = false
}

// 暴露方法给父组件
defineExpose({
  handleShowDialog
})
</script>

<template>
  <el-dialog
    v-model="visible"
    title="环境设置"
    width="600px"
    :close-on-click-modal="false"
  >
    <el-form
      ref="formRef"
      :model="formState"
      label-position="right"
      :label-width="120"
    >
      <el-form-item
        label="环境对象名称"
        prop="envObjName"
        :rules="[{ required: true, message: '请输入环境对象名称', trigger: 'change' }]"
      >
        <div class="name-input-container">
          <el-input
            v-if="editName"
            v-model="formState.envObjName"
            class="edit-name"
          />
          <el-select
            v-else
            v-model="formState.id"
            placeholder="请选择"
            style="width: 260px"
            @change="handleChange"
          >
            <el-option
              v-for="item in options"
              :key="item.id"
              :label="item.envObjName"
              :value="item.id"
            />
          </el-select>

          <div class="action-icons">
            <el-tooltip content="新增" placement="top" v-if="!editName">
              <el-icon @click="plus">
                <Plus />
              </el-icon>
            </el-tooltip>
            <el-tooltip content="删除" placement="top" v-if="!editName">
              <el-icon @click="minus(formState.id)">
                <Minus />
              </el-icon>
            </el-tooltip>
            <el-tooltip content="编辑" placement="top">
              <el-icon @click="editNameClick">
                <Edit />
              </el-icon>
            </el-tooltip>
          </div>
        </div>
      </el-form-item>

      <el-form-item
        label="海况等级"
        prop="seaStateLevel"
        :rules="[{ required: true, message: '请设置海况等级' }]"
      >
        <div class="slider-container">
          <el-slider
            v-model="formState.seaStateLevel"
            :max="9"
            :min="0"
            :marks="marks"
            style="width: 80%"
          />
          <el-input-number
            v-model="formState.seaStateLevel"
            :min="0"
            :max="9"
            :controls="false"
            style="width: 60px"
          />
        </div>
      </el-form-item>

      <el-form-item
        label="风向"
        prop="windCou"
        class="pt-5"
        :rules="[{ required: true, message: '请设置风向' }]"
      >
        <div class="form-item-row">
          <Compass :rotate="formState.windCou" @update-rotate="updateRotate" />
          <el-input-number
            v-model="formState.windCou"
            :min="0"
            :max="360"
            :controls="false"
            style="width: 60px; margin-left: 10px"
          />
        </div>
      </el-form-item>

      <el-form-item
        label="风速"
        prop="windVel"
        :rules="[{ required: true, message: '请设置风速' }]"
      >
        <el-input-number
          v-model="formState.windVel"
          :precision="2"
          :controls="false"
          :step="0.01"
        >
          <template #suffix>
            km/h
          </template>
        </el-input-number>
      </el-form-item>
    </el-form>

    <template #footer>
      <el-button @click="handleCancel">
        取消
      </el-button>
      <el-button type="primary" :loading="confirmLoading" @click="handleConfirm">
        确定
      </el-button>
    </template>
  </el-dialog>
</template>

<style lang="scss" scoped>
.form-item-row {
  display: flex;
  flex-direction: row;
  align-items: center;
}

.name-input-container {
  display: flex;
  align-items: center;

  .edit-name {
    width: 260px;
    margin-right: 10px;
  }
}

.action-icons {
  display: flex;
  margin-left: 10px;

  .el-icon {
    cursor: pointer;
    margin-right: 8px;
    font-size: 16px;
    color: var(--el-color-primary);

    &:hover {
      color: var(--el-color-primary-light-3);
    }
  }
}

.slider-container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
}
</style>
